from PIL import ImageGrab,Image
import time
from ctypes import *
from time import sleep
import  win32con, win32gui
from Ui_untitled import Ui_mir4main
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox
import sys
import _thread
import smtplib
from email.mime.text import MIMEText
from email.header import Header

# 第三方 SMTP 服务
mail_host="smtp.qq.com"  #设置服务器
mail_user="1501138908@qq.com"    #用户名
mail_pass="xxxxxxxxxxxxxxxxxx"   #口令 

#方便调用Windows底层API函数
user32 = windll.user32
kernel32 = windll.kernel32
psapi = windll.psapi

def sent_email(recever):
    sender = '1501138908@qq.com'
    message = MIMEText(recever+'mir4提醒，请上线查看', 'plain', 'utf-8')
    message['From'] = Header("mir4", 'utf-8')
    message['To'] =  Header("user", 'utf-8')
    subject = 'mir4提醒服务'
    message['Subject'] = Header(subject, 'utf-8')
    try:
        smtpObj = smtplib.SMTP() 
        smtpObj.connect(mail_host, 25)    # 25 为 SMTP 端口号
        smtpObj.login(mail_user,mail_pass)  
        smtpObj.sendmail(sender, recever, message.as_string())
        print("邮件发送成功")
    except smtplib.SMTPException:
        print("Error: 无法发送邮件")

# 通过顶层窗口获取窗口的句柄
def getProcessHwnd():
    #获取当前位于桌面最顶端的窗口句柄
    hwnd = user32.GetForegroundWindow()
    return hwnd


# https://blog.csdn.net/weixin_39121325/article/details/84187453
# 将图片转化为RGB，需要与原图片具有比较符合答size，否则准确率较低
def make_regalur_image(img,size=(800,800)):
    gray_image=img.resize(size).convert('RGB')
    return gray_image

# 计算直方图
def hist_similar(lh,rh):
    assert len(lh)==len(rh)
    hist=sum(1-(0 if l==r else float(abs(l-r))/max(l,r)) for l,r in zip(lh,rh))/len(lh)
    return hist

# 计算相似度
def calc_similar(li,ri):
    calc_sim=hist_similar(li.histogram(),ri.histogram())
    return calc_sim


def myfunc(winNum,winTime,winPosition,winEmail):
    # process('0')
    # sent_message()

    # 图片的保存路径
    localtion=str(winPosition)

    # 存储窗口句柄
    pro_set=set()

    # 需要监控的窗口数量
    Max_set_size=int(winNum)

    # i用于图片比较的切换
    i=0

    # 获取句柄的间隔时间，单位秒
    sleep_ju=3
    # 监控的时间间隔，单位秒
    sleep_jk=int(winTime)

    # 获取窗口句柄
    time.sleep(3)
    while len(pro_set)<Max_set_size:
        hwnd=getProcessHwnd()
        print(hwnd)
        pro_set.add(hwnd)
        time.sleep(sleep_ju)

    # 循环监控
    cnt=0
    while True:
        # 获取所有窗口的当前状态
        
        for item in pro_set:
            print(item)
            name=str(item)+str(i)+'.jpg'
            # i=i+1
            x1,y1,x2,y2=win32gui.GetWindowRect(item)
            win32gui.SendMessage(item, win32con.WM_SYSCOMMAND, win32con.SC_RESTORE, 0)
            print(x1, y1, x2, y2)
            text = win32gui.SetForegroundWindow(item)

            # 窗口转换保留间隔时间
            time.sleep(1)
            img_ready = ImageGrab.grab((x1, y1, x2, y2))
            img_ready.save(localtion+name)
            # img_ready.show()
        # 图片切换，只保留两张
        if i==0:
            i=1
        else:
            i=0
        # 避免第一次运行程序没有两张图片
        cnt=cnt+1
        if cnt<2:
            continue
        # 与上一次窗口状态进行比较
        for item in pro_set:
            name1=name=str(item)+'0.jpg'
            name2=name=str(item)+'1.jpg'
            image1=Image.open(localtion+name1)
            image2=Image.open(localtion+name2)

            # RGB化
            image1=make_regalur_image(image1)
            image2=make_regalur_image(image2)

            similar=calc_similar(image1,image2)
            print(similar)
            if similar<0.5:
                # 传递信息
                sent_email(winEmail)
                print('!!!!!!!!!!!!!!!!!!!!!!')
        time.sleep(sleep_jk)
        print('finish')



# 主界面
class parentWin(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.main_ui=Ui_mir4main()
        self.main_ui.setupUi(self)
        self.main_ui.pushButton.clicked.connect(self.start)
        self.main_ui.pushButton_2.clicked.connect(self.end)

    def showMessageBox(self,msg):
        res = QMessageBox.about(self, "结果",str(msg))

    def start(self):
        winNum=str(self.main_ui.lineEdit.text())
        winTime=str(self.main_ui.lineEdit_2.text())
        winPosition=str(self.main_ui.lineEdit_3.text())
        winEmail=str(self.main_ui.lineEdit_5.text())
        # 开始后不能再按
        self.main_ui.pushButton.setEnabled(False)
        # 创建线程
        try:
            _thread.start_new_thread(myfunc,(winNum,winTime,winPosition,winEmail,))
        except:
            print("无法启动线程")
        

    def end(self):
        sys.exit()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    # ftp(host,port,username,password,win_path,linux_path)
    window=parentWin()
    window.show()
    sys.exit(app.exec_())